/*
 * Copyright (C) 2022 Huawei Technologies Co., Ltd.
 * Licensed under the Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *     http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
 * PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
#ifndef SE_SERVICE_SESRV_API_H
#define SE_SERVICE_SESRV_API_H

#include "tee_defines.h"
#include <dlist.h>
#include "tee_internal_se_api.h"

struct se_transmit_info_t {
    uint32_t reader_id;
    uint8_t channel_id;
    uint8_t *data;
    uint32_t data_len;
    uint8_t *p_rsp;
    uint32_t rsp_len;
};

#define SE_UUID                                            \
    {                                                      \
        0x91f0cf6b, 0xbd4b, 0x456e,                        \
        {                                                  \
            0x86, 0x2d, 0x3f, 0xa6, 0x1a, 0xb1, 0xa4, 0xac \
        }                                                  \
    }

struct __TEE_SEServiceHandle {
    int *se_mutex;
};

struct __TEE_SEReaderHandle {
    unsigned int id;
    TEE_SEReaderProperties property;
    bool basic_channel_locked;
    unsigned short session_count;
    unsigned short atr_len;
    uint8_t atr[ATR_LEN_MAX];
    const char *name;
    struct dlist_node session_head;
    uint8_t logic_channel_bm[(SE_LOGIC_CHANNEL_MAX + BYTE_LEN - 1) / BYTE_LEN];
    int *se_channel_mutex;
};

struct __TEE_SESessionHandle {
    int8_t state; // 0 - closed, 1 - open, -1 - invalid
    unsigned char channel_count;
    short reserved;
    TEE_SEReaderHandle reader;
    struct dlist_node list;
    struct dlist_node channel_head;
};

struct __TEE_SEChannelHandle {
    TEE_SEAID se_aid;
    bool basic_channel;
    unsigned char logic_channel;
    unsigned short resp_len;
    uint8_t *resp_buffer;
    TEE_SESessionHandle session;
    struct dlist_node list;
    bool is_secure;
};

typedef struct __TEE_SEServiceHandle *TEE_SEServiceHandle;
typedef struct __TEE_SEReaderHandle *TEE_SEReaderHandle;
typedef struct __TEE_SESessionHandle *TEE_SESessionHandle;
typedef struct __TEE_SEChannelHandle *TEE_SEChannelHandle;

bool se_srv_exist(void);
int se_srv_get_ese_type(void);
TEE_Result se_srv_connect(uint32_t reader_id, uint8_t *p_atr, uint32_t *atr_len);
TEE_Result se_srv_disconnect(uint32_t reader_id);
TEE_Result tee_se_srv_transmit(struct se_transmit_info_t *transmit_info);
TEE_Result tee_se_srv_open_basic_channel(struct se_transmit_info_t *transmit_info);
TEE_Result tee_se_srv_open_logical_channel(struct se_transmit_info_t *transmit_info);
TEE_Result tee_se_srv_close_channel(const struct se_transmit_info_t *transmit_info);
TEE_Result tee_se_srv_select_channel(struct se_transmit_info_t *transmit_info);
bool se_srv_get_msp_status(void);
bool se_srv_get_sec_flash_status(void);
#endif
